package boundary;

import java.awt.Color;

import translate.Translate;
import desktop_fields.*;
import desktop_resources.GUI;
import fields.Ownable;
import entities.Inventory;
import fields.*;
import gstd.Dice;
import gstd.Field;
import gstd.Player;

public class GUIManager implements UI {
	boolean animationActive;

	@Override
	public void init(boolean useAnimation, Field[] fields) {
		desktop_fields.Field[] guiFields = new desktop_fields.Field[fields.length];
		animationActive = useAnimation;
		for (int i = 0; i < fields.length; i++) {

			Field field = fields[i];
			Class<?> fieldClass = field.getClass();

			// Set Territory field
			if (fieldClass.equals(Territory.class)) {
				guiFields[i] = new Street.Builder().setBgColor(Color.GREEN).build();

			}

			// Set Fleet field
			else if (fieldClass.equals(Fleet.class)) {
				guiFields[i] = new Shipping.Builder().setBgColor(Color.BLUE).build();

			}

			// Set Tax field
			else if (fieldClass.equals(fields.Tax.class)) {
				guiFields[i] = new desktop_fields.Tax.Builder().setBgColor(Color.RED).build();

			}

			// Set LaborCamp field
			else if (fieldClass.equals(LaborCamp.class)) {
				guiFields[i] = new Brewery.Builder().setBgColor(Color.CYAN).build();

			}

			// Set Refuge field
			else if (fieldClass.equals(fields.Refuge.class)) {
				guiFields[i] = new desktop_fields.Tax.Builder().setBgColor(Color.PINK).build();
			}

			guiFields[i].setTitle(field.getName());
			guiFields[i].setSubText(field.toString());
			guiFields[i].setDescription(field.getName());

		}

		GUI.create(guiFields);

	}

	@Override
	public void selectShake(Player player) {
		GUI.getUserButtonPressed(playerTurnString(player) + Translate.print("Roll the dice."), Translate.print("roll"));

	}

	@Override
	public void showDices(final Dice[] dices) {
		if (animationActive) {
			int x1, x2, y1, y2;

			int area = 6;
			do {
				x1 = (int) (Math.random() * area) + (area / 2);
				x2 = (int) (Math.random() * area) + (area / 2);
				y1 = (int) (Math.random() * area) + (area / 2);
				y2 = (int) (Math.random() * area) + (area / 2);
			} while (x1 == x2 && y1 == y2 || Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) > 3);
			DiceAnimation da = new DiceAnimation(dices);
			da.setPositions(x1, x2, y1, y2);
			da.getLoop().run();
			GUI.setDice(dices[0].getValue(), x1, y1, dices[1].getValue(), x2, y2);
		} else
			GUI.setDice(dices[0].getValue(), dices[1].getValue());
	}

	@Override
	public void updatePlayers(Player[] players) {
		for (int i = 0; i < players.length; i++) {
			GUI.setBalance(players[i].getName(), players[i].getInventory().getBalance());
		}
	}

	@Override
	public boolean askToBuy(Ownable ownableField, Player player) {
		return GUI.getUserLeftButtonPressed(playerTurnString(player) + Translate.print("Do you want to buy %s for the cost of %d?", ownableField.getName(), ownableField.getPrice()), Translate
				.print("Buy"), Translate.print("Decline"));
	}

	@Override
	public void updateBoard(Field[] fields) {
		for (int i = 0; i < fields.length; i++) {
			// Checks if the field has an owner and updates the UI
			if (fields[i] instanceof Ownable) {
				Ownable ownableField = (Ownable) fields[i];
				if (ownableField.getOwner() == null) {
					GUI.removeOwner(i + 1);
				} else {
					GUI.setOwner(i + 1, ((Ownable) fields[i]).getOwner().getName());
				}
				// If not removes the owner from the UI
			}
		}
	}

	@Override
	public void setPlayerBankrupt(Player player, Field[] fields) {
		GUI.removeAllCars(player.getName());
		updateBoard(fields);
		GUI.showMessage(playerTurnString(player) + Translate.print("You have become bankrupt!"));
	}

	@Override
	public int selectNumberOfPlayers() {
		return GUI.getUserInteger(Translate.print("Enter number of players."), 2, 6);

	}

	@Override
	public String inputPlayerName(int nr) {
		return GUI.getUserString(Translate.print("Enter name of Player %d", nr + 1));
	}

	@Override
	public void createPlayers(Player[] players) {
		for (int i = 0; i < players.length; i++) {
			GUI.addPlayer(players[i].getName(), players[i].getInventory().getBalance());
		}
	}

	@Override
	public void move(int field, Player player) {
		GUI.removeAllCars(player.getName());
		GUI.setCar(field + 1, player.getName());
	}

	@Override
	public void resetBoard(Field[] fields, Player[] players) {
		for (int i = 1; i <= fields.length; i++) {
			GUI.removeOwner(i);
		}
		for (int i = 0; i < players.length; i++) {
			GUI.removeAllCars(players[i].getName());
			GUI.setBalance(players[i].getName(), players[i].getInventory().getBalance());
		}
	}

	@Override
	public boolean selectStartNewMatch() {
		return GUI.getUserLeftButtonPressed(Translate.print("Do you want to start a new match or exit the game?"), Translate.print("start new match"), Translate.print("exit game"));
	}

	@Override
	public void payRent(Player player, Player owner, int rent) {
		GUI.showMessage(playerTurnString(player) + Translate.print("You paid a rent of %d to %s.", rent, owner.getName()));
	}

	@Override
	public void receiveBonus(Player player, int bonus) {
		GUI.showMessage(playerTurnString(player) + Translate.print("You received a bonus of %d.", bonus));
	}

	private String playerTurnString(Player player) {
		return Translate.print("%s's turn. ", player.getName());
	}

	@Override
	public void payTax(Player player, int tax) {
		GUI.showMessage(playerTurnString(player) + Translate.print("You paid a tax of %d.", tax));

	}

	@Override
	public void showWinner(Player winner) {
		GUI.showMessage(Translate.print("The winner is %s with a total asset of %d. Start a new match?", winner.getName(), ((Inventory) winner.getInventory()).getTotalAssets()));
	}

}
